package top.jfunc.http.interceptor;

import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import top.jfunc.common.utils.MultiValueMap;
import top.jfunc.http.component.CompletedUrlCreator;
import top.jfunc.http.component.DefaultCompletedUrlCreator;
import top.jfunc.http.component.ribbon.RibbonInit;
import top.jfunc.http.holder.DefaultPhpUrlHolder;
import top.jfunc.http.holder.ParamHolder;
import top.jfunc.http.request.HttpRequest;
import top.jfunc.common.utils.ParamUtil;

import java.io.IOException;

public class LoadBalancerInterceptor implements Interceptor {
    private static final Logger logger = LoggerFactory.getLogger(LoadBalancerInterceptor.class);
    private CompletedUrlCreator completedUrlCreator = new DefaultCompletedUrlCreator();
    @Override
    public HttpRequest onBefore(HttpRequest httpRequest) throws IOException {
        String url = completedUrlCreator.complete(httpRequest);
        DefaultPhpUrlHolder phpUrlHolder = new DefaultPhpUrlHolder();
        phpUrlHolder.setUrl(url);

        String host = phpUrlHolder.host();
        BaseLoadBalancer loadBalancer = RibbonInit.get(host);
        if(null == loadBalancer){
            logger.warn("根据 {} 未找到LoadBalancer，请检查是否调用RibbonInit进行初始化",host);
            return httpRequest;
        }
        Server server = loadBalancer.chooseServer();
        if(null == server){
            logger.warn("根据 {} 未找到合适的服务器。。。", host);
            return httpRequest;
        }
        //修改ip和端口为选中的服务器的
        phpUrlHolder.host(server.getHost());
        phpUrlHolder.port(server.getPort());
        String holderUrl = handleQueryParamIfNecessary(phpUrlHolder);
        httpRequest.setUrl(holderUrl);

        return httpRequest;
    }

    private String handleQueryParamIfNecessary(DefaultPhpUrlHolder phpUrlHolder) {
        String holderUrl = phpUrlHolder.getUrl();
        ParamHolder paramHolder = phpUrlHolder.queryParamHolder();
        MultiValueMap<String, String> multiValueMap = paramHolder.get();
        if(null != multiValueMap && !multiValueMap.isEmpty()){
            holderUrl = ParamUtil.contactUrlParams(holderUrl, multiValueMap, paramHolder.getParamCharset());
        }
        return holderUrl;
    }

    public void setCompletedUrlCreator(CompletedUrlCreator completedUrlCreator) {
        this.completedUrlCreator = completedUrlCreator;
    }
}
